<?php

# primesfactory
# coded by Alessandro Rosa
# e-mail : zandor_zz@yahoo.it
# site : http://malilla.supereva.it

# Copyright (C) 2006  Alessandro Rosa

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA

class PrimesFactory {

	var $factors;
	var $exponents;

	var $number;
	var $err_no;
	var $err_msg;
	var $style_id;  // 0 for plain, 1 for html, 2 for TeX/LaTeX2e

	function __construct() {
		$this->reset();
	}

	function reset() {
		$this->number = 0;

		$this->factors = array();
		$this->exponents = array();

		$this->err_no = -1;
		$this->err_msg = "";

		$this->style_id = 1;

		// however you can set it to the number of seconds
		// or to 0 whether you want to remove any execution time limit
		ini_set('max_execution_time', 0);
	}

	function set_style($id ) {
		$this->style_id = $id;
	}

	function get_style() {
		return $this->style_id;
	}

	function isok() {
		return $this->err_no == -1 ? true : false;
	}

	function display_error() {
		switch ($this->err_no) {
			case 1:
				$this->err_msg = "The number $this->number is not integer;";
				break;
			case 2:
				$this->err_msg = "The string $this->number does not appear to be a valid number;";
				break;
			default:
				break;
		}

		echo "<font color=red><b>$this->err_msg</b></font>";
	}

	function insertNumber($n) {
		$this->number = $n ;

		$this->factors = array();
		$this->exponents = array();
	}

	function isnumeric($sText) {
		$ValidChars = "0123456789";

		for ($i = 0; $i < strlen($sText) - 1; $i++) {
			$Char = $sText{$i};

			if (strpos($ValidChars, $Char) === false) {
				return 1;
			}
		}

		return 0;
	}

	function isdecimal($n) {
		$val = $n + 0;

		if (($n - $val) == 0) return 0;
		else return 1;
		// this means that ",00" was the decimal part: so it's integer

		if (strpos($n, ".") > 0 || strpos($n, ",") > 0) return 1;

		return 0;
	}

	function isprime($n) {
		for ($i = 2; $i <= $n - 1; $i++) {
			if ($n % $i == 0) return false;
		}

		return true;
	}

	function isperfect() {
		$sum = 0;

		for ($i = 1; $i < $this->number; $i++) {
			if ($this->number % $i == 0) $sum += $i;
		}

		return $sum == $this->number ? true : false;
	}

	function primesbefore() {
		$count = 0;

		for ($i = 1; $i < $this->number; $i++) {
			if ($this->isprime($i)) $count++;
		}

		return $count;
	}


	function go() {
		$err_catch = 0;

		if ($this->isdecimal($this->number)) {
			$this->err_no = 1;
			return ;
		} else if ($this->isnumeric($this->number)) {
			$this->err_no = 2;
			return;
		}

		$this->factorization($this->number) ;
	}

	function factorization($n) {
		if ($n == 1) {
			$this->add_factor(1) ;
			return;
		}

		$remainder = -1;

		for ($i = 2; $i <= $n; $i++) {
			$remainder = $n % $i;

			if ($this->isprime($i) && $remainder == 0) {
				$this->add_factor($i);

				$n /= $i;

				$i = 1;
				// $i is set to 1 : the next loop will increment it to 2,
				// so we are in the conditions to restart the factorization
			}
		}
	}

	function add_factor($factor) {
		$n_elements = count($this->factors);

		$bADD = true;

		for ($i = 0; $i < $n_elements; $i++) {
			if ($this->factors[$i] == $factor) {
				$bADD = false;
				break;
			}
		}

		if ($bADD) {
			// create a new entry in the array
			// and fills it with the new factor entry

			$this->factors[$i] = $factor;
			$this->exponents[$i] = 1;
		} else {
			// the factor was found, so only the related exponent
			// shall be updated
			// $this->factors[ $i ] = $factor ;

			$this->exponents[$i]++;
		}

		return true;
	}

	function display() {
		$ret_str = "";
		$n_elements = count($this->factors);

		if ($this->style_id == 2) $ret_str .= "$"; // TeX/LaTeX opener for mathematical formulas

		for ($i = 0; $i < $n_elements; $i++) {
			if ($this->exponents[$i] > 1) {
				$ret_str .= $this->factors[$i];

				switch ($this->style_id) {
					case 0:
						$ret_str .= "^";
						break;
					case 1:
						$ret_str .= "<sup>";
						break;
					case 2:
						$ret_str .= "^{";
						break;
				}

				$ret_str .= $this->exponents[$i];

				switch ($this->style_id) {
					case 0:
						$ret_str .= "";
						break;
					case 1:
						$ret_str .= "</sup>";
						break;
					case 2:
						$ret_str .= "}";
						break;
				}
			} else {
				$ret_str .= $this->factors[$i];
			}

			if ($i < $n_elements - 1) {
				switch ($this->style_id) {
					case 0:
						$ret_str .= " x ";
						break;
					case 1:
						//$ret_str .= "&bull;";
						$ret_str .= " * ";
						break;
					case 2:
						$ret_str .= "\\times";
						break;
				}
			}
		}

		if ($this->style_id == 2) $ret_str .= "$"; // TeX/LaTeX closer for mathematical formulas

		return $ret_str;
	}

}
